﻿/**************************************************************
 *
 * 唯一标识：66e4619c-617c-4f8c-80f5-fa9691a823a9
 * 命名空间：Sgr.UPMS
 * 创建时间：2023/8/28 13:47:46
 * 机器名称：DESKTOP-S0D075D
 * 创建者：antho
 * 电子邮箱：fengqinhua2016@163.com
 * 描述：
 *
 **************************************************************/

using Sgr.Caching;

namespace Sgr.UPMS
{
    /// <summary>
    /// 缓存键模板和常用缓存配置工厂
    /// 说明：对现有代码仅做分区、添加中文注释，不改变行为或签名
    /// </summary>
    public static class CacheKeys
    {
        #region 缓存过期时间常量（以小时/分钟为单位，供创建 CacheEntryOptions 使用）

        /// <summary>
        /// ORG 基础数据缓存 绝对过期时间（小时）
        /// </summary>
        private const int CacheOrgBasicDataAbsoluteExpirationHours = 24;    // ORG 基础数据缓存绝对过期时间（24小时）

        /// <summary>
        /// ORG 基础数据缓存 滑动过期时间（分钟）
        /// </summary>
        private const int CacheOrgBasicDataSlidingExpirationMinutes = 30;   // ORG 基础数据缓存滑动过期时间（30分钟）

        /// <summary>
        /// 菜单缓存 绝对过期时间（分钟）
        /// </summary>
        private const int CacheMenuAbsoluteExpirationMinutes = 60 * 24 * 1;  // 缓存绝对过期时间（1天）

        /// <summary>
        /// 权限相关缓存 绝对过期时间（分钟）
        /// </summary>
        private const int CachePermissionAbsoluteExpirationMinutes = 60;  // 缓存绝对过期时间（60分钟）

        /// <summary>
        /// 权限相关缓存 滑动过期时间（分钟）
        /// </summary>
        private const int CachePermissionSlidingExpirationMinutes = 5;    // 缓存滑动过期时间（5分钟）

        #endregion 缓存过期时间常量（以小时/分钟为单位，供创建 CacheEntryOptions 使用）

        #region 缓存键模板 - 授权/用户/权限相关

        /// <summary>
        /// 用户在某组织下的权限（按用户）缓存键模板
        /// 参数：
        /// {0} - 组织ID (OrgId)
        /// {1} - 用户ID (UserId)
        /// </summary>
        public const string AUTH_ORG_USER_KEY = "sgr:org:{0}:user:{1}:permissions";

        /// <summary>
        /// 按组织与权限（permission）缓存的用户集合键模板（用于按权限查找用户）
        /// 参数：
        /// {0} - 组织ID（字符串）
        /// {1} - 权限代码
        /// </summary>
        public const string USER_PERMISSION_KEY = "sgr:org:{0}:user:perm:{1}";

        #endregion 缓存键模板 - 授权/用户/权限相关

        #region 缓存键模板 - 菜单相关

        /// <summary>
        /// 所有菜单缓存键（针对全局/单例菜单数据）
        /// </summary>
        public const string MENU_KEY = "sgr:menu";

        /// <summary>
        /// 根据权限集合 Hash 获取关联菜单列表缓存键模板
        /// 参数：
        /// {0} - 权限项集合的 Hash 值
        /// </summary>
        public const string PERMISSIONS_MENU_KEY = "sgr:menus:{0}:permissions";

        #endregion 缓存键模板 - 菜单相关

        #region 缓存键模板 - 组织相关

        /// <summary>
        /// 组织信息缓存键模板
        /// 参数：
        /// {0} - 组织ID (OrgId)
        /// </summary>
        public const string ORG_KEY = "sgr:org:{0}:info";

        #endregion 缓存键模板 - 组织相关

        #region 缓存键模板 - 部门相关

        /// <summary>
        /// 组织下所有部门缓存键模板
        /// 参数：
        /// {0} - 组织ID (OrgId)
        /// </summary>
        public const string ORG_DEPARTMENTS_KEY = "sgr:org:{0}:departments";

        #endregion 缓存键模板 - 部门相关

        #region 缓存键模板 - 岗位相关

        /// <summary>
        /// 组织下所有岗位缓存键模板
        /// 参数：
        /// {0} - 组织ID (OrgId)
        /// </summary>
        public const string ORG_DUTIES_KEY = "sgr:org:{0}:duties";

        #endregion 缓存键模板 - 岗位相关

        #region 缓存键模板 - 用户相关（部门主管等）

        /// <summary>
        /// 按部门获取部门主管缓存键模板
        /// 参数：
        /// {0} - 部门ID（字符串）
        /// </summary>
        public const string USER_DEPT_MANAGER_KEY = "sgr:org:{0}:dept:{1}:manager";

        #endregion 缓存键模板 - 用户相关（部门主管等）

        #region 缓存键格式化方法（Key 生成辅助方法）

        /// <summary>
        /// 获取用户权限（基于 org string, permission）的缓存键
        /// </summary>
        /// <param name="org">组织 ID（字符串）</param>
        /// <param name="permission">权限代码</param>
        public static string GetUserPermissionKey(string org, string permission) => string.Format(USER_PERMISSION_KEY, org, permission);

        /// <summary>
        /// 获取按部门查部门主管的缓存键
        /// </summary>
        /// <param name="orgId">组织 ID（字符串）</param>
        /// <param name="deptId">部门 ID（字符串）</param>
        public static string GetDeptManagerDeptKey(string orgId, string deptId) => string.Format(USER_DEPT_MANAGER_KEY, orgId, deptId);

        /// <summary>
        /// 获取组织下所有缓存键前缀（便于清除组织相关所有缓存）
        /// </summary>
        /// <param name="orgId">组织 ID（长整型）</param>
        public static string GetOrgAllKeyPrefix(long orgId)
            => string.Format("sgr:org:{0}", orgId);

        /// <summary>
        /// 获取组织信息的缓存键（格式化 ORG_KEY）
        /// </summary>
        /// <param name="orgId">组织 ID</param>
        public static string GetOrgKey(long orgId)
            => string.Format(ORG_KEY, orgId);

        /// <summary>
        /// 获取组织下所有部门的缓存键（格式化 ORG_DEPARTMENTS_KEY）
        /// </summary>
        /// <param name="orgId">组织 ID</param>
        public static string GetOrgDepartmentsKey(long orgId)
            => string.Format(ORG_DEPARTMENTS_KEY, orgId);

        /// <summary>
        /// 获取组织下所有岗位的缓存键（格式化 ORG_DUTIES_KEY）
        /// </summary>
        /// <param name="orgId">组织 ID</param>
        public static string GetOrgDutiesKey(long orgId)
            => string.Format(ORG_DUTIES_KEY, orgId);

        /// <summary>
        /// 获取指定组织和用户的权限缓存键（格式化 AUTH_ORG_USER_KEY）
        /// </summary>
        /// <param name="orgId">组织 ID</param>
        /// <param name="userId">用户 ID</param>
        public static string GetUserPermissionKey(long orgId, long userId)
            => string.Format(AUTH_ORG_USER_KEY, orgId, userId);

        /// <summary>
        /// 获取用于缓存所有菜单信息的键
        /// </summary>
        public static string GetAllMenusKey() => MENU_KEY;

        /// <summary>
        /// 获取指定权限项集合关联的菜单列表缓存键（格式化 PERMISSIONS_MENU_KEY）
        /// </summary>
        /// <param name="permissionsCode">权限项集合的 Hash</param>
        public static string GetPermissionsMenusKey(string permissionsCode)
            => string.Format(PERMISSIONS_MENU_KEY, permissionsCode);

        #endregion 缓存键格式化方法（Key 生成辅助方法）

        #region 缓存选项创建方法（返回 CacheEntryOptions 的工厂方法）

        /// <summary>
        /// 创建用户权限缓存配置选项（用于单用户权限缓存）
        /// 绝对过期：CachePermissionAbsoluteExpirationMinutes 分钟
        /// 滑动过期：CachePermissionSlidingExpirationMinutes 分钟
        /// </summary>
        public static CacheEntryOptions CreateUserPermissionCacheOptions()
        {
            return new CacheEntryOptions()
                .SetAbsoluteExpirationRelativeToNowSecond(CachePermissionAbsoluteExpirationMinutes * 60)
                .SetSlidingExpirationSecond(CachePermissionSlidingExpirationMinutes * 60);
        }

        /// <summary>
        /// 创建权限->菜单 关联缓存配置选项
        /// 绝对过期：CachePermissionAbsoluteExpirationMinutes 分钟
        /// 滑动过期：CachePermissionSlidingExpirationMinutes 分钟
        /// </summary>
        public static CacheEntryOptions CreatePermissionMenuCacheOptions()
        {
            return new CacheEntryOptions()
                .SetAbsoluteExpirationRelativeToNowSecond(CachePermissionAbsoluteExpirationMinutes * 60)
                .SetSlidingExpirationSecond(CachePermissionSlidingExpirationMinutes * 60);
        }

        /// <summary>
        /// 创建菜单缓存配置选项（按天过期）
        /// 绝对时间点：UTCNow + CacheMenuAbsoluteExpirationMinutes
        /// </summary>
        public static CacheEntryOptions CreateMeunCacheOptions()
        {
            return new CacheEntryOptions()
                .SetAbsoluteExpiration(DateTime.UtcNow.AddMinutes(CacheMenuAbsoluteExpirationMinutes));
        }

        #region 其他缓存选项

        /// <summary>
        /// 为从部门主管表加载用户信息的缓存配置（短 TTL，避免频繁变动时长期失效）
        /// </summary>
        public static CacheEntryOptions CreateUserFromDepManagerCacheOptions()
        {
            return new CacheEntryOptions().SetAbsoluteExpirationRelativeToNowSecond(300); // 5分钟
        }

        /// <summary>
        /// 为按权限查找用户的缓存配置（短 TTL，避免权限变动时长期缓存）
        /// </summary>
        public static CacheEntryOptions CreateUserFromPermissionCacheOptions()
        {
            return new CacheEntryOptions().SetAbsoluteExpirationRelativeToNowSecond(300); // 5分钟
        }

        /// <summary>
        /// 创建组织基础数据缓存（部门/岗位/组织名称）配置选项
        /// 绝对过期：CacheOrgBasicDataAbsoluteExpirationHours 小时
        /// 滑动过期：CacheOrgBasicDataSlidingExpirationMinutes 分钟
        /// </summary>
        public static CacheEntryOptions CreateOrgBasicDataCacheOptions()
        {
            return new CacheEntryOptions()
                .SetAbsoluteExpirationRelativeToNowSecond(CacheOrgBasicDataAbsoluteExpirationHours * 3600)
                .SetSlidingExpirationSecond(CacheOrgBasicDataSlidingExpirationMinutes * 60);
        }

        #endregion 其他缓存选项

        #endregion 缓存选项创建方法（返回 CacheEntryOptions 的工厂方法）
    }
}